package com.giantlizard.cloud.gateway.config;

import com.giantlizard.cloud.gateway.config.properties.IgnoreWhiteProperties;
import com.giantlizard.cloud.gateway.filter.AuthFilter;
import com.giantlizard.cloud.gateway.handler.GlobalExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository;
import org.springframework.security.web.server.context.ServerSecurityContextRepository;

/**
 * 网关安全配置
 * 
 * @author GiantLizard
 */
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    private final GlobalExceptionHandler globalExceptionHandler;

    private final AuthFilter authFilter;

    private final IgnoreWhiteProperties ignoreWhite;

    public SecurityConfig(GlobalExceptionHandler globalExceptionHandler, AuthFilter authFilter, IgnoreWhiteProperties ignoreWhite) {
        this.globalExceptionHandler = globalExceptionHandler;
        this.authFilter = authFilter;
        this.ignoreWhite = ignoreWhite;
    }

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        String[] whitelist = ignoreWhite.getWhites().toArray(new String[0]);
        http
                // 禁用basic认证
                .httpBasic().disable()
                // 禁用form认证
                .formLogin().disable()
                // 禁用csrf
                .csrf().disable()
                // 禁用默认登录
                .anonymous().disable()
                .addFilterBefore(authFilter, SecurityWebFiltersOrder.AUTHORIZATION)

                // 配置路由权限
                .authorizeExchange()
                // 白名单放行
                .pathMatchers(whitelist).permitAll()
                // 其他请求需要认证
                .anyExchange().authenticated()
                .and()
                // 异常处理
                .exceptionHandling()
                .authenticationEntryPoint(globalExceptionHandler)
                .accessDeniedHandler(globalExceptionHandler);

        return http.build();
    }

    @Bean
    public ServerSecurityContextRepository securityContextRepository() {
        return NoOpServerSecurityContextRepository.getInstance();
    }
} 